package com.googlecode.spoluyan.google.googlebooks;

import java.util.HashMap;
import java.util.Map;

import com.googlecode.spoluyan.google.common.AbstractGoogleAPIClient;
import com.googlecode.spoluyan.google.common.Defines;
import com.googlecode.spoluyan.google.common.Utils;
import com.googlecode.spoluyan.google.common.Defines.GoogleBooksDefines.AdditionalParameter;
import com.googlecode.spoluyan.google.common.Defines.GoogleBooksDefines.Filter;
import com.googlecode.spoluyan.google.common.Defines.GoogleBooksDefines.OrderBy;
import com.googlecode.spoluyan.google.common.Defines.GoogleBooksDefines.PrintType;
import com.googlecode.spoluyan.google.googlebooks.data.BookShelves;
import com.googlecode.spoluyan.google.googlebooks.data.BooksVolumes;
import com.googlecode.spoluyan.google.googlebooks.data.Shelf;
import com.googlecode.spoluyan.google.googlebooks.data.Volume;

public class GoogleBooksClient extends AbstractGoogleAPIClient {

    public GoogleBooksClient(String key) {
	super(key);
    }

    public BooksVolumes searchVolumes(String query, Map<AdditionalParameter, String> fields, String download,
	    Filter filter, Integer startIndex, Integer maxResults, PrintType printType, OrderBy orderBy) {
	if (Utils.isEmptyString(query)) {
	    return null;
	}
	if (fields != null && fields.size() > 0) {
	    StringBuilder q = new StringBuilder(query);
	    for (AdditionalParameter ap : fields.keySet()) {
		String val = fields.get(ap);
		if (!Utils.isEmptyString(val)) {
		    q.append(Defines.PLUS).append(ap.getName()).append(Defines.COLON).append(val);
		}
	    }
	    query = q.toString();
	}

	Map<String, String> queryParams = new HashMap<String, String>();
	queryParams.put(Defines.GoogleBooksDefines.Parameter.QUERY, query);

	if (!Utils.isEmptyString(download)) {
	    queryParams.put(Defines.GoogleBooksDefines.Parameter.DOWNLOAD, download);
	}
	if (filter != null) {
	    queryParams.put(Defines.GoogleBooksDefines.Parameter.FILTER, filter.getName());
	}
	if (startIndex != null) {
	    int val = startIndex.intValue();
	    if (val > 0) {
		queryParams.put(Defines.GoogleBooksDefines.Parameter.START_INDEX, String.valueOf(val));
	    }
	}
	if (maxResults != null) {
	    int val = startIndex.intValue();
	    if (val > 0) {
		if (val > 40) {
		    val = 40;
		}
		queryParams.put(Defines.GoogleBooksDefines.Parameter.MAX_RESULTS, String.valueOf(val));
	    }
	}
	if (printType != null) {
	    queryParams.put(Defines.GoogleBooksDefines.Parameter.PRINT_TYPE, printType.getName());
	}
	if (orderBy != null) {
	    queryParams.put(Defines.GoogleBooksDefines.Parameter.ORDER_BY, orderBy.getName());
	}
	return Utils.fromJSON(Utils.doRequest(key, queryParams, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.VOLUMES), BooksVolumes.class);
    }

    public Volume getVolume(String volumeId) {
	if (Utils.isEmptyString(volumeId)) {
	    return null;
	}
	return Utils.fromJSON(Utils.doRequest(key, null, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.VOLUMES, Defines.SLASH, volumeId), Volume.class);
    }

    public BookShelves getBookShelves(String userId) {
	if (Utils.isEmptyString(userId)) {
	    return null;
	}
	return Utils.fromJSON(Utils.doRequest(key, null, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.USERS, userId, Defines.SLASH,
		Defines.GoogleBooksDefines.Path.BOOKSHELVES), BookShelves.class);
    }

    public Shelf getShelf(String userId, Long shelfId) {
	if (Utils.isEmptyString(userId) || shelfId == null) {
	    return null;
	}
	long val = shelfId.longValue();
	if (val < 0) {
	    return null;
	}
	return Utils.fromJSON(Utils.doRequest(key, null, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.USERS, userId, Defines.SLASH,
		Defines.GoogleBooksDefines.Path.BOOKSHELVES, Defines.SLASH, String.valueOf(val)), Shelf.class);
    }

    public BooksVolumes getVolumes(String userId, Long shelfId, Integer startIndex, Integer maxResults) {
	if (Utils.isEmptyString(userId) || shelfId == null) {
	    return null;
	}

	long sId = shelfId.longValue();
	if (sId < 0) {
	    return null;
	}

	Map<String, String> queryParams = new HashMap<String, String>();
	if (startIndex != null) {
	    int val = startIndex.intValue();
	    if (val > 0) {
		queryParams.put(Defines.GoogleBooksDefines.Parameter.START_INDEX, String.valueOf(val));
	    }
	}
	if (maxResults != null) {
	    int val = startIndex.intValue();
	    if (val > 0) {
		if (val > 40) {
		    val = 40;
		}
		queryParams.put(Defines.GoogleBooksDefines.Parameter.MAX_RESULTS, String.valueOf(val));
	    }
	}
	return Utils.fromJSON(Utils.doRequest(key, queryParams, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.USERS, userId, Defines.SLASH,
		Defines.GoogleBooksDefines.Path.BOOKSHELVES, Defines.SLASH, String.valueOf(sId), Defines.SLASH,
		Defines.GoogleBooksDefines.Path.VOLUMES), BooksVolumes.class);
    }

    // TODO need OAuth token
    private BookShelves getMyLibraryBookShelves() {
	return Utils.fromJSON(Utils.doRequest(key, null, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.MY_LIBRARY, Defines.GoogleBooksDefines.Path.BOOKSHELVES),
		BookShelves.class);
    }

    // TODO need OAuth token
    private BooksVolumes getMyLibraryVolumes(Long shelfId, Integer startIndex, Integer maxResults) {
	if (shelfId == null) {
	    return null;
	}

	long sId = shelfId.longValue();
	if (sId < 0) {
	    return null;
	}

	Map<String, String> queryParams = new HashMap<String, String>();
	if (startIndex != null) {
	    int val = startIndex.intValue();
	    if (val > 0) {
		queryParams.put(Defines.GoogleBooksDefines.Parameter.START_INDEX, String.valueOf(val));
	    }
	}
	if (maxResults != null) {
	    int val = startIndex.intValue();
	    if (val > 0) {
		if (val > 40) {
		    val = 40;
		}
		queryParams.put(Defines.GoogleBooksDefines.Parameter.MAX_RESULTS, String.valueOf(val));
	    }
	}
	return Utils.fromJSON(Utils.doRequest(key, queryParams, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.MY_LIBRARY, Defines.GoogleBooksDefines.Path.BOOKSHELVES, Defines.SLASH,
		String.valueOf(sId), Defines.SLASH, Defines.GoogleBooksDefines.Path.VOLUMES), BooksVolumes.class);
    }

    // TODO need OAuth token
    private void addVolume(Long shelfId, String volumeId) {
	if (shelfId == null || Utils.isEmptyString(volumeId)) {
	    return;
	}
	long sId = shelfId.longValue();
	if (sId < 0) {
	    return;
	}

	Map<String, String> queryParams = new HashMap<String, String>();
	queryParams.put(Defines.GoogleBooksDefines.Parameter.VOLUME_ID, volumeId);

	Utils.doRequest(key, queryParams, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.MY_LIBRARY, Defines.GoogleBooksDefines.Path.BOOKSHELVES, Defines.SLASH,
		String.valueOf(sId), Defines.SLASH, Defines.GoogleBooksDefines.Path.ADD_VOLUME);
    }

    // TODO need OAuth token
    private void removeVolume(Long shelfId, String volumeId) {
	if (shelfId == null || Utils.isEmptyString(volumeId)) {
	    return;
	}
	long sId = shelfId.longValue();
	if (sId < 0) {
	    return;
	}

	Map<String, String> queryParams = new HashMap<String, String>();
	queryParams.put(Defines.GoogleBooksDefines.Parameter.VOLUME_ID, volumeId);

	Utils.doRequest(key, queryParams, Defines.GoogleBooksDefines.API_URL,
		Defines.GoogleBooksDefines.Path.MY_LIBRARY, Defines.GoogleBooksDefines.Path.BOOKSHELVES, Defines.SLASH,
		String.valueOf(sId), Defines.SLASH, Defines.GoogleBooksDefines.Path.REMOVE_VOLUME);
    }

    // TODO need OAuth token
    private void clearVolumes(Long shelfId) {
	if (shelfId == null) {
	    return;
	}
	long sId = shelfId.longValue();
	if (sId < 0) {
	    return;
	}
	Utils.doRequest(key, null, Defines.GoogleBooksDefines.API_URL, Defines.GoogleBooksDefines.Path.MY_LIBRARY,
		Defines.GoogleBooksDefines.Path.BOOKSHELVES, Defines.SLASH, String.valueOf(sId), Defines.SLASH,
		Defines.GoogleBooksDefines.Path.CLEAR_VOLUMES);
    }
}
